﻿using System;
using System.Collections.ObjectModel;
using System.Linq;
using DynamicData;
using LuckyFish.ToDo.Data;
using LuckyFish.ToDo.Data.Model;

namespace LuckyFish.ToDo.ViewModels;

public class MainWindowViewModel : ViewModelBase
{
    #region Pror

    private bool _isShow = true;
    public bool IsShow
    {
        get => _isShow;
        set => SetField(ref _isShow, value);
    }
    
    private ToDoContext Data { get; set; }
    public ObservableCollection<ToDoGroupModel> GroupModels { get; set; }

    private object? _content;

    public object? Content
    {
        get => _content;
        set => SetField(ref _content, value);
    }

    #endregion

    #region Load

    private ToDoGroupModel GroupLoad(ToDoGroupModel group)
    {
        Data.Entry(group).Collection(x => x.ToDos).Load();
        return group;
    }

    public ToDoModel TodoLoad(ToDoModel todo)
    {
        Data.Entry(todo).Collection(x => x.Steps).Load();
        return todo;
    }

    #endregion

    #region View

    public void ToGroupView(ToDoGroupModel group)
    {
        Content = GroupLoad(group);
    }

    public void ToToDoView(ToDoModel todo)
    {
        Content = TodoLoad(todo);
    }

    public void ToAddGroupView() => Content = "AddGroup";

    public void ToWelcomeView()
    {
        var a = Data.ToDos.ToList();
        Content = new WelcomeViewModel(a.Where(x => DateTime.Parse(x.EndTime) >= DateTime.Today));
    }

    public void Side()
    {
        IsShow = !IsShow;
    }

    #endregion

    #region DataOperation

    #region Add

    public void Add(ToDoGroupModel? model)
    {
        if (model == null) return;
        Data.Groups.Add(model);
        Data.SaveChanges();
    }

    public void Add(ToDoModel? todo, int key)
    {
        if (todo == null) return;
        var group = Data.Groups.FirstOrDefault(x => x.Key == key);
        if (group == null) return;
        group.ToDos.Add(todo);
        Data.SaveChanges();
        Update();
        Content = group;
    }

    public void Add(ToDoModel todo)
    {
        Data.ToDos.Add(todo);
        Data.SaveChanges();
    }

    public void Add(StepModel? step, int key)
    {
        if (step == null) return;
        var todo = Data.ToDos.FirstOrDefault(x => x.Key == key);
        if (todo == null) return;
        todo.Steps.Add(step);
        Data.SaveChanges();
        Update();
    }

    #endregion

    #region Update

    private void Update()
    {
        GroupModels.Clear();
        GroupModels.Add(Data.Groups);
    }

    public void Update(ToDoGroupModel group)
    {
        var model = Data.Groups.FirstOrDefault(x => x.Key == group.Key);
        if (model is null) return;
        model = group;
        Data.SaveChanges();
        Update();
    }

    public void Update(ToDoModel todo)
    {
        var model = Data.ToDos.FirstOrDefault(x => x.Key == todo.Key);
        if (model is null) return;
        model = todo;
        Data.SaveChanges();
        Update();
    }

    public void Update(StepModel step)
    {
        var model = Data.Steps.FirstOrDefault(x => x.Key == step.Key);
        if (model is null) return;
        model = step;
        Data.SaveChanges();
        Update();
    }

    #endregion

    #region Remove

    public void RemoveGroup(ToDoGroupModel model)
    {
        Data.Remove(model);
        Data.SaveChanges();
        Update();
    }
    
    public void RemoveTodo(ToDoModel model)
    {
        Data.Remove(model);
        Data.SaveChanges();
        Update();
    }
    
    public void RemoveStep(StepModel model)
    {
        Data.Remove(model);
        Data.SaveChanges();
        Update();
    }

    #endregion

    #region Get

    public ToDoModel? GetTodo(int key)
        => Data.ToDos.FirstOrDefault(x => x.Key == key);

    #endregion

    #endregion

    public MainWindowViewModel()
    {
        Data = new ToDoContext();
        ToWelcomeView();
        GroupModels = new ObservableCollection<ToDoGroupModel>(Data.Groups);
    }
}